﻿using FaceWebServer.Utility.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Threading.Tasks;

namespace FaceWebServer.Utility.Middleware
{
    public class ExceptionMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILogger<ExceptionMiddleware> _logger;
        

        public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> log)
        {
            this.next = next;
            _logger = log;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                var ret = context.Request;
                var rep = context.Response;

                var responseOriginalBody = rep.Body;
                using (var memStream = new MemoryStream())
                {
                    rep.Body = memStream;
                    await next.Invoke(context);
                    if (context.Response.StatusCode != 200)
                    {
                        //处理执行其他中间件后的ResponseBody
                        memStream.Position = 0;
                        var responseReader = new StreamReader(memStream);
                        var responseBody = await responseReader.ReadToEndAsync();

                        _logger.LogError($"{ret.Method} URL:{ret.Path} : {context.Response.StatusCode}");


                        var result = new JsonResultModel(10000 + context.Response.StatusCode, responseBody);

                        rep.Body = responseOriginalBody;
                        rep.Clear();
                        rep.StatusCode = 200;
                        rep.ContentType = "application/json; charset=utf-8";

                        await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
                    }
                    else
                    {
                        memStream.Position = 0;
                        await memStream.CopyToAsync(responseOriginalBody);
                        rep.Body = responseOriginalBody;
                    }
                }

                //var features = context.Features;
            }
            catch (Exception e)
            {
                await HandleException(context, e);
            }
        }

        private async Task HandleException(HttpContext context, Exception e)
        {
            var req = context.Request;
            var rst = context.Response;
            _logger.LogError($"{req.Method} URL:{req.Path} : {e.ToString()}");
            var result = new JsonResultModel(10100, e.Message);
            rst.Clear();
            rst.StatusCode = 200;
            rst.ContentType = "application/json; charset=utf-8";
            await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
        }
    }
}
